package com.iretailer.report.web.system;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iretailer.report.base.BaseAction;
import com.iretailer.report.common.InternationalMessage;
import com.iretailer.report.dto.PageResult;
import com.iretailer.report.dto.QueryOption;
import com.iretailer.report.dto.ReUser;
import com.iretailer.report.easyexcel.data.UserData;
import com.iretailer.report.easyexcel.listener.UserDataListener;
import com.iretailer.report.model.*;
import com.iretailer.report.service.report.UserControllerAsync;
import com.iretailer.report.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Auther: xjw
 * @Date: 2019/1/28 10:47
 * @Description:
 */
@RestController
public class UserController extends BaseAction {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);
    @Autowired
    private UserControllerAsync userControllerAsync;

    @RequestMapping("/system/userInfo.action")
    public Map<String, Object> userInfo(HttpServletRequest request) {
        User userInfo = SecurityUserUtil.currentUser(request);
        User newUserInfo = userService.getById(userInfo.getId());
        Map<String, Object> data = new HashMap<>();
        Map<String, Future> futureMap = new HashMap<>();

        Future<List<Menus>> menusFutrue = userControllerAsync.assembleMenus(newUserInfo);
        futureMap.put("Menus", menusFutrue);


        Future<String> showLogo = userControllerAsync.showLogo(newUserInfo.getCompanyId());
        futureMap.put("ShowLogo", showLogo);
//        data.put("ShowLogo", showLogo);

//        List<PageWidgets> userPageWidgets = pageWidgetService.selectPageWidgetsByUserId(newUserInfo.getId());
//        data.put("PageWidget", userPageWidgets);
        Future<List<PageWidgets>> userPageWidgets = userControllerAsync.pageWidgets(newUserInfo.getId());
        futureMap.put("PageWidget", userPageWidgets);

        List<Malls> malls;
        // malls 按照 Ranked 和 Name 排序
        if (StringUtil.notEmpty(newUserInfo.getRoleId()) && newUserInfo.getRoleId().equals("-")) {
            malls = mallsService.list(new QueryWrapper<Malls>().lambda().eq(Malls::getEnabled, 1).orderByAsc(Malls::getRanked).orderByAsc(Malls::getName));
        } else {
            // 过滤重复的
            malls = mallsService.selectMallsByUserId_enabled(newUserInfo.getId(), 1);
        }
//         查询出案场的所有区域
        List<String> mallIds = malls.stream().map(Malls::getId).collect(Collectors.toList());

        Future<List<JSONObject>> mallObjectFutrue = userControllerAsync.assembleMalls(malls, mallIds);
        futureMap.put("Malls", mallObjectFutrue);

        Future<List<MallTagType>> tagTypeFutrue = userControllerAsync.assembleTagType(mallIds);
        futureMap.put("TagTypes", tagTypeFutrue);


        data.put("UserId", newUserInfo.getId());
        data.put("RoleId", newUserInfo.getRoleId());
        data.put("Name", newUserInfo.getName());
        data.put("Email", newUserInfo.getEmail());
        data.put("Telephone", newUserInfo.getTelephone());
        data.put("Language", newUserInfo.getLanguage());
        futureMap.entrySet().forEach(it -> {
            try {
                Object object = it.getValue().get();
                data.put(it.getKey(), object);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        });
        return RMap.ok(data);
    }

    @RequestMapping("/system/userSetting.action")
    public Map<String, Object> userSetting(@RequestBody ReUser reUser,HttpServletRequest request) {
         User user = SecurityUserUtil.currentUser(request);
        User insert = modelMapper.map(reUser, User.class);
        insert.setId(user.getId());
        boolean result = userService.saveOrUpdate(insert, null, user.getName());
        return RMap.resultBoolean(result);
    }

    @RequestMapping("/system/gridUser.action")
    public Map<String, Object> gridUser(@RequestBody ReUser reUser,HttpServletRequest request) {
         User user = SecurityUserUtil.currentUser(request);
        QueryOption queryOption = modelMapper.map(reUser, QueryOption.class);
        String parentId = user.getId();
        if (user.getRoleId().equals("-")) {
            parentId = null;
        }
        PageResult<UserRole> result = userService.grid(parentId, reUser.getCompanyName(), reUser.getUserCode(), reUser.getName(), reUser.getRoleName(), queryOption);
        return RMap.ok(result);
    }

    @RequestMapping("/system/selectUserByParentId.action")
    public Map<String, Object> selectUserByParentId(HttpServletRequest request) {
         User user = SecurityUserUtil.currentUser(request);
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        if (!user.getRoleId().equals("-")) {
            queryWrapper.lambda().eq(User::getParentId, user.getParentId());
        }
        List<User> result = userService.list(queryWrapper);
        return RMap.ok(result);
    }

    @RequestMapping("/system/saveOrUpdateUser.action")
    public Map<String, Object> saveOrUpdate(@RequestBody ReUser reUser,HttpServletRequest request) {
        LambdaQueryWrapper<Config> wrapper = new QueryWrapper<Config>().lambda().eq(Config::getConfigKey, "password_regex");
        Config pr = configService.getOne(wrapper);
        if (pr != null && StringUtil.notEmpty(pr.getConfigValue())) {
            String password = reUser.getUserPwd();
            List<Map<String, Object>> prMaps = JsonUtil.json2list(pr.getConfigValue());
            for (Map<String, Object> prMap : prMaps) {
                String regex = (String) prMap.get("regex");
                String errorMsg = (String) prMap.get("errorMsg");
                if (!Pattern.matches(regex, password)) {
                    return RMap.error(errorMsg);
                }
            }
        }
         User user = SecurityUserUtil.currentUser(request);
        User insert = modelMapper.map(reUser, User.class);
        boolean result = userService.saveOrUpdate(insert, user.getId(), user.getName());
        return RMap.resultBoolean(result);
    }

    @RequestMapping("/system/saveUserMalls.action")
    public Map<String, Object> saveUserMalls(@RequestBody ReUser reUser) {
        boolean result = userMallService.insertUsersMalls(reUser.getId(), reUser.getMallIds());
        return RMap.resultBoolean(result);
    }


    @RequestMapping("/system/delUser.action")
    public Map<String, Object> del(@RequestBody List<String> ids) {
        boolean result = userService.deleteByIds(ids);
        return RMap.resultBoolean(result);
    }

    @RequestMapping("/system/resetPassword.action")
    public Map<String, Object> resetPassword(@RequestBody ReUser reUser,HttpServletRequest request) {
         User user = SecurityUserUtil.currentUser(request);
        boolean result = userService.resetPassword(reUser.getId(), reUser.getPassword(), user.getName());
        return RMap.resultBoolean(result);
    }

    @RequestMapping("/system/changePassword.action")
    public Map<String, Object> changePassword(@RequestBody ReUser reUser,HttpServletRequest request) {
        String password = reUser.getUserPass();
        Config pr = configService.getOne(new QueryWrapper<Config>().eq("ConfigKey", "password_regex"));
        if (pr != null && !StringUtil.empty(pr.getConfigValue())) {
            for (Map<String, Object> prMap : JsonUtil.json2list(pr.getConfigValue())) {
                String regex = (String) prMap.get("regex");
                String errorMsg = (String) prMap.get("errorMsg");
                if(!Pattern.matches(regex,password)){
                    return RMap.error(errorMsg);
                }
            }
        }
         User user = SecurityUserUtil.currentUser(request);
        //每次修改都去查询最新的数据
        User find = userService.getById(user.getId());
        if (find.getUserPwd().equals(MD5Util.getMd5(reUser.getOldPassword()))) {
            boolean result = userService.resetPassword(user.getId(), reUser.getUserPwd(), user.getName());
            return result ? RMap.ok("ok") :RMap.error("reset_password_failed");
        }
        return RMap.error("the_old_password_is_incorrect");
    }

    @RequestMapping("/system/unlock.action")
    public Map<String, Object> unlock(@RequestBody ReUser reUser) {
        boolean result = userService.updateLock(reUser.getId(), 0, LocalDateTime.now());
        return RMap.resultBoolean(result);
    }

    @RequestMapping("/system/saveUserWidget.action")
    public Map<String, Object> saveUserWidget(@RequestBody ReUser reUser,HttpServletRequest request) {
         User user = SecurityUserUtil.currentUser(request);
        List<PageWidgets> pageWidgets = reUser.getPageWidgets();
        if (pageWidgets == null) {
            List<PageWidgets> result = pageWidgetService.list(new QueryWrapper<PageWidgets>().lambda().eq(PageWidgets::getMobile, -1).orderByAsc(PageWidgets::getRanked));
            return RMap.ok(result);
        } else {
            boolean result = pageWidgetService.replacePageWidgets_users(pageWidgets, user.getId());
            return RMap.resultBoolean(result);
        }
    }

    @RequestMapping("/system/getUserWidget.action")
    public Map<String, Object> getUserWidget(HttpServletRequest request) {
         User user = SecurityUserUtil.currentUser(request);
        List<PageWidgets> result = pageWidgetService.selectPageWidgetsByUserId(user.getId());
        return RMap.ok(result);
    }

    @RequestMapping("/system/selectUserByCompanyId.action")
    public Map<String, Object> selectUserByCompanyId(@RequestBody ReUser reUser) {
        if (StringUtil.notEmpty(reUser.getCompanyId())) {
            List<UserRole> users = userService.selectUserRole(new QueryWrapper<>().eq("CompanyId", reUser.getCompanyId()));
            return RMap.ok(users);
        } else {
            return RMap.error();
        }
    }


    @RequestMapping("/system/importUserExcelData.action")
    public Map<String, Object> importUserExcelData(@RequestParam("file") MultipartFile file, HttpServletRequest request) {

        String language = SecurityUserUtil.userLanguage(request);
        if (file == null || file.isEmpty()) {
            return RMap.error(InternationalMessage.EMPTY_UPLOAD_FILE.getByLanguage(language));
        }
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            return RMap.error(InternationalMessage.FAILED_UPLOAD_FILE.getByLanguage(language));
        }
        UserDataListener userDataListener = new UserDataListener(request);
        try {
            EasyExcel.read(inputStream, UserData.class, userDataListener).sheet().doRead();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RMap.error(e.getMessage());
        }
        return RMap.ok(userDataListener.getUserDataList());
    }
}
